package org.example.mallchat.common.intecepter;

import cn.hutool.core.util.ObjectUtil;
import org.example.mallchat.service.LoginService;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * @author: zzh
 * @date: 2024/12/22 16:20:36
 * @version: 1.0
 */
@Order(-2)// 保证该拦截器在所有拦截器之前执行
@Component//Spring的拦截器，用于验证token 判断是否需要登录！
public class TokenIntercepter implements HandlerInterceptor {
    @Resource
    private LoginService loginService;

    @Override
    public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
        // 获取token
        String token = getTokenByHeader(request);
        // 校验是否有效token 是否登录态
        Long validUid = loginService.getValidUid(token);
        if (ObjectUtil.isNotNull(validUid)){// 登录态有效
            // 登录态有效，放行 同时将用户id放入request中
            request.setAttribute("uid", validUid);
        }else {//登录态无效，再去判断我们的想要访问的接口是否是公共的 (是否包含/public)
            String requestURI = request.getRequestURI();
            if (requestURI.contains("/public")){
                // 公共接口，放行
                return true;
            }else{
                // 非公共接口，返回401 前端跳转到登录页面
                response.sendError(401, "请先登录！");
                response.setContentType("text/html;charset=UTF-8");
                response.getWriter().println("");
                return false;
            }
        }
        return true;
    }

    private String getTokenByHeader(HttpServletRequest request) {
        // 我们会在Authorization头部中获取token
        String authorization = request.getHeader("Authorization");
        // 需要判断是否有token 且要以Bearer开头
        if (authorization != null && authorization.startsWith("Bearer ")){
            String token = authorization.replace("Bearer ", "");
            // 将这个token放在request中后续
            return token;
        }
        return null;
    }
}
